﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Linq;


namespace TMS
{
    public class AplicacionXMLManager:XMLBaseManager
    {
        private static AplicacionXMLManager _instancia;

        public static AplicacionXMLManager getInstancia()
        {
            if (_instancia == null)
            {
                _instancia = new AplicacionXMLManager();
            }
            return _instancia;
        }

        private AplicacionXMLManager()
        {
            nombreRoot = "Aplicaciones";
            nombreArchivo = nombreRoot + ".xml";
        }

        public void addAplicacion(Aplicacion pAplicacion)
        {
            XDocument xDoc = loadDoc(); //Carga el documento.
            XElement aplicaciones = xDoc.Root; //Obtiene la raiz del documento XML.
            /*
             * El codigo siguiente verifica que no haya una aplicacion registrada en el sistema con el mismo nombre.
             * Se intenta cargar la variable "app" con un elemento del documento XML que tenga el mismo nombre; en caso 
             * de no existir tal elemento se agrega el nuevo elemento con los datos del objeto que se recibe como 
             * parametro.
             */ 
          
                XElement aplicacion = new XElement("Aplicacion"); //Genera un nuevo elemento.
                aplicacion.SetAttributeValue("Id", "" + pAplicacion.Id); //Agrega Id como atributo.
                aplicacion.SetElementValue("Nombre", pAplicacion.Nombre); //Agrega el nombre de la aplicacion.
                aplicacion.SetElementValue("Descripcion", pAplicacion.Descripcion); //Agrega la descripcion
                aplicaciones.Add(aplicacion); //Agrega el elemento definido antes a la raiz del documento.
                saveDoc(xDoc); //Guarda el documento.
            
        }
        public void updateAplicacion(Aplicacion pAplicacion)
        {
            /* 
             * Actualiza los datos de una aplicacion almacenada en el documento XML con los datos contenidos en la instancia
             * de Aplicacion que se recibe como parametro. Para encontrar la aplicacion almacenada se utiliza el numero de Id, 
             * que es el unico dato que no se puede cambiar en el formulario de modificacion.
             */
            XDocument xDoc = loadDoc();
            XElement app = xDoc.Root.Elements().Single(ap => (long)ap.Attribute("Id") == pAplicacion.Id);
            app.SetElementValue("Nombre", pAplicacion.Nombre);
            app.SetElementValue("Descripcion", pAplicacion.Descripcion);
            saveDoc(xDoc);
        }
        public void removeAplicacion(long pAppId)
        {
            /*
             * Primero elimina todos los modulos relacionados con la aplicacion cuyo Id se recibe como parametro.
             * Luego se elimina dicha aplicacion.
             */
            ModuloXMLManager.getInstancia().removeModsByIdApp(pAppId);
            this.removeById(pAppId);
        }
        public Aplicacion getAplicacionByName(string pNom)
        {
            /*
             * Recibe el nombre de una aplicacion, busca en el documento XML la aplicacion correspondiente, carga sus datos 
             * dentro de una instancia de Aplicacion y devuelve dicha instancia.
             */
            Aplicacion a = new Aplicacion();
            XDocument xDoc = loadDoc();

            try
            {
                XElement app = xDoc.Root.Elements().Single(ap => (string)ap.Element("Nombre") == pNom);
                if (app != null)
                {
                    a.Id = long.Parse(app.Attribute("Id").Value);
                    a.Nombre = pNom;
                    a.Descripcion = "" + app.Element("Descripcion").Value;
                }
            }
            catch (InvalidOperationException ioe)
            {
                a = null;
            }
            return a;
        }
        public Aplicacion getAplicacionById(long pAppId)
        {
            /*
             * Recibe el numero de Id de una aplicacion, busca en el documento XML la aplicacion correspondiente, carga sus datos 
             * dentro de una instancia de Aplicacion y devuelve dicha instancia.
             */
            Aplicacion a = new Aplicacion();
            XDocument xDoc = loadDoc();
            XElement app = xDoc.Root.Elements().Single(ap => (long)ap.Attribute("Id") == pAppId);
            a.Id = pAppId;
            a.Nombre = "" + app.Element("Nombre").Value;
            a.Descripcion = "" + app.Element("Descripcion").Value;
            return a;
        }
        public List<Aplicacion> getAppList()
        {
            /*
             * Devuelve una lista con todas las aplicaciones almacenadas en el sistema.
             */ 
            List<Aplicacion> lstApp = new List<Aplicacion>();
            XDocument xDoc = loadDoc();
            foreach (XElement xe in xDoc.Root.Elements())
            {
                Aplicacion a = new Aplicacion();
                a.Id = long.Parse(xe.Attribute("Id").Value);
                a.Nombre = xe.Element("Nombre").Value;
                a.Descripcion = xe.Element("Descripcion").Value;
                lstApp.Add(a);
            }
            return lstApp;
        }
        public bool existeAplicacion(string pNombre)
        {
            /*
             * Comprueba que no exista una aplicacion registrado con ese nombre.
             */
            bool existe = false;
            XDocument xDoc = loadDoc(); //Carga el documento.
            try
            {
                XElement xEl = xDoc.Root.Elements().Single(a => (string)a.Element("Nombre") == pNombre);
                if (xEl != null)
                {
                    existe = true;
                }
            }
            catch (InvalidOperationException)
            {
                existe = false;
            }
            return existe;
        }
        
    }
}